package task

import (
	"context"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"goproject/commonType"
	ctrl "sigs.k8s.io/controller-runtime"
)

var log = ctrl.Log.WithName("mongo/task")

type Store struct {
	Collection *mongo.Collection
}

func NewStore(db *mongo.Database) *Store {
	return &Store{
		Collection: db.Collection("task"),
	}
}

// Create 创建测试任务
func (s *Store) Create(ctx context.Context, task commonType.Task) (commonType.Task, error) {
	result, err := s.Collection.InsertOne(ctx, task)
	if err != nil {
		log.Error(err, "insert task error", "task", task)
		return commonType.Task{}, err
	}
	objectID := result.InsertedID.(primitive.ObjectID)
	task.ID = &objectID
	return task, nil
}

// Get 获取测试任务
func (s *Store) Get(ctx context.Context, id primitive.ObjectID) (commonType.Task, error) {
	var task commonType.Task
	err := s.Collection.FindOne(ctx, primitive.M{"_id": id}).Decode(&task)
	if err != nil {
		log.Error(err, "get task error", "id", id)
		return commonType.Task{}, err
	}
	return task, nil
}

// 获取所有任务
func (s *Store) GetAll(ctx context.Context) ([]commonType.Task, error) {
	var tasks []commonType.Task
	cursor, err := s.Collection.Find(ctx, bson.D{})
	if err != nil {
		log.Error(err, "list task error, find error")
		return nil, err
	}
	err = cursor.All(ctx, &tasks)
	if err != nil {
		log.Error(err, "list task error, decode error")
	}
	return tasks, nil
}

// List 获取测试任务列表
func (s *Store) List(ctx context.Context) ([]commonType.Task, error) {
	var tasks []commonType.Task
	cursor, err := s.Collection.Find(ctx, primitive.M{})
	if err != nil {
		log.Error(err, "list task error, find error")
		return nil, err
	}
	err = cursor.All(ctx, &tasks)
	if err != nil {
		log.Error(err, "list task error, decode error")
		return nil, err
	}
	return tasks, nil
}

// Update 更新测试任务
func (s *Store) Update(ctx context.Context, id primitive.ObjectID, task commonType.Task) error {
	_, err := s.Collection.UpdateOne(ctx, primitive.M{"_id": id}, primitive.M{"$set": task})
	if err != nil {
		log.Error(err, "update task error", "id", id, "task", task)
		return err
	}
	return nil
}

// Delete 删除测试任务
func (s *Store) Delete(ctx context.Context, id primitive.ObjectID) error {
	_, err := s.Collection.DeleteOne(ctx, primitive.M{"_id": id})
	if err != nil {
		log.Error(err, "delete task error", "id", id)
		return err
	}
	return nil
}

// DeleteAll 删除所有测试任务
func (s *Store) DeleteAll(ctx context.Context) error {
	_, err := s.Collection.DeleteMany(ctx, primitive.M{})
	if err != nil {
		log.Error(err, "delete all task error")
		return err
	}
	return nil
}

// 分页查询 Task
func (s *Store) GetByPage(ctx context.Context, skip int, pageSize int) ([]commonType.Task, error) {
	findOptions := options.Find()
	findOptions.SetSkip(int64(skip))
	findOptions.SetLimit(int64(pageSize))
	cursor, err := s.Collection.Find(context.TODO(), bson.D{}, findOptions)
	if err != nil {
		log.Error(err, "get task by page error")
		return nil, err
	}
	if err != nil {
		log.Error(err, "查询任务失败: %v")
		return nil, err
	}
	var tasks []commonType.Task
	if err = cursor.All(context.TODO(), &tasks); err != nil {
		log.Error(err, "解析任务失败: %v")
		return nil, err
	}
	return tasks, err
}
